package SGEngine

import (
	//"fmt"
	gl "github.com/gl"
)

type FreetypeLabel struct {
	Node
	Mfont     *FreetypeFont
	Text      string
	Color     Color3
	VBuffer   gl.Buffer
	TexBuffer gl.Buffer
	MProgram  *Program
	FontSize  int
}

func CreateFTLabel(_font *FreetypeFont, _text string, _size int) *FreetypeLabel {
	RFTLabel := new(FreetypeLabel)
	RFTLabel.Mfont = _font
	RFTLabel.Text = _text
	RFTLabel.Node = DefaultNode()
	RFTLabel.SetSizeV(VecOne)
	RFTLabel.NodeRender = RFTLabel
	RFTLabel.GetTransfrom().SetIsSizeScale(false)
	RFTLabel.VBuffer = gl.GenBuffer()
	RFTLabel.TexBuffer = gl.GenBuffer()
	RFTLabel.MProgram = ACProgramMgr.GetProgram(PROGRAM_IMG)
	uniformTexture := RFTLabel.MProgram.ProgramObject.GetUniformLocation("s_texture")
	uniformTexture.Uniform1i(0)
	RFTLabel.FontSize = _size
	RFTLabel.Color = WhiteColor
	RFTLabel.SetText(_text)
	return RFTLabel
}

func (f *FreetypeLabel) SetText(_text string) {
	f.Text = _text
	f.FillVertexBuffer()
}

func (f *FreetypeLabel) FillVertexBuffer() {
	StrLen := len([]rune(f.Text))
	arrayBuffer := make([]float32, StrLen*18)
	TexBuffer := make([]float32, StrLen*12)

	i := 0
	j := 0

	OffsetX := float32(0.0)
	OffSetY := float32(f.FontSize) * 0.45
	for _, V := range f.Text {
		if V == ' ' {
			OffsetX += float32(f.FontSize) * 0.5
			continue
		}
		fontchar := f.Mfont.GetChar(V, f.FontSize)
		OffsetX += float32(fontchar.AdvanceX)
	}
	OffsetX = OffsetX * 0.5

	AdvanceX := float32(0)
	for _, V := range f.Text {
		if V == ' ' {
			AdvanceX += float32(f.FontSize) * 0.5
			continue
		}

		fontchar := f.Mfont.GetChar(V, f.FontSize)
		MinX := float32(fontchar.BBox.XMin) + AdvanceX
		MaxX := float32(fontchar.BBox.XMax) + AdvanceX
		MinY := float32(fontchar.BBox.YMin)
		MaxY := float32(fontchar.BBox.YMax)
		//v0
		arrayBuffer[i] = MinX - OffsetX
		arrayBuffer[i+1] = MinY - OffSetY
		arrayBuffer[i+2] = 0
		//v1
		arrayBuffer[i+3] = MaxX - OffsetX
		arrayBuffer[i+4] = MinY - OffSetY
		arrayBuffer[i+5] = 0
		//v2
		arrayBuffer[i+6] = MinX - OffsetX
		arrayBuffer[i+7] = MaxY - OffSetY
		arrayBuffer[i+8] = 0
		//v3
		arrayBuffer[i+9] = MaxX - OffsetX
		arrayBuffer[i+10] = MinY - OffSetY
		arrayBuffer[i+11] = 0
		//v4
		arrayBuffer[i+12] = MaxX - OffsetX
		arrayBuffer[i+13] = MaxY - OffSetY
		arrayBuffer[i+14] = 0
		//v5
		arrayBuffer[i+15] = MinX - OffsetX
		arrayBuffer[i+16] = MaxY - OffSetY
		arrayBuffer[i+17] = 0
		i += 18

		TMinX := float32(fontchar.Rect.X) / float32(fontchar.Mfont.TextureAtlas[fontchar.AtlasIndex].Width)
		TMaxX := float32(fontchar.Rect.X+fontchar.Rect.Width) / float32(fontchar.Mfont.TextureAtlas[fontchar.AtlasIndex].Width)
		TMaxY := float32(fontchar.Mfont.TextureAtlas[fontchar.AtlasIndex].Height-fontchar.Rect.Y) / float32(fontchar.Mfont.TextureAtlas[fontchar.AtlasIndex].Height)
		TMinY := float32(fontchar.Mfont.TextureAtlas[fontchar.AtlasIndex].Height-fontchar.Rect.Y-fontchar.Rect.Height) / float32(fontchar.Mfont.TextureAtlas[fontchar.AtlasIndex].Height)
		//tv0
		TexBuffer[j] = TMinX
		TexBuffer[j+1] = TMinY
		//tv1
		TexBuffer[j+2] = TMaxX
		TexBuffer[j+3] = TMinY
		//tv2
		TexBuffer[j+4] = TMinX
		TexBuffer[j+5] = TMaxY
		//tv3
		TexBuffer[j+6] = TMaxX
		TexBuffer[j+7] = TMinY
		//tv4
		TexBuffer[j+8] = TMaxX
		TexBuffer[j+9] = TMaxY
		//tv5
		TexBuffer[j+10] = TMinX
		TexBuffer[j+11] = TMaxY
		j += 12
		AdvanceX += float32(fontchar.AdvanceX)
	}
	f.SetSize(float64(AdvanceX), float64(f.FontSize), 1)
	f.VBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, StrLen*18*4, arrayBuffer, gl.STATIC_DRAW)
	f.TexBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, StrLen*12*4, TexBuffer, gl.STATIC_DRAW)

}
func (l *FreetypeLabel) Render() {
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	//gl.Enable(gl.ALPHA_TEST)
	//gl.AlphaFunc(gl.GREATER, 0.1)
	gl.Enable(gl.TEXTURE_2D)
	gl.ActiveTexture(gl.TEXTURE0)
	l.Mfont.TextureAtlas[0].Tex.TexID.Bind(gl.TEXTURE_2D)
	//l.LabelFont.BMFontData.FontTexture.TexID.Bind(gl.TEXTURE_2D)
	l.MProgram.ProgramObject.Use()
	l.MProgram.ProgramObject.GetUniformLocation("inColor").Uniform4f(l.Color.R, l.Color.G, l.Color.B, 1)
	l.VBuffer.Bind(gl.ARRAY_BUFFER)
	l.MProgram.ProgramObject.GetAttribLocation("vPosition").AttribPointer(3, gl.FLOAT, false, 0, nil)
	l.MProgram.ProgramObject.GetAttribLocation("vPosition").EnableArray()
	l.TexBuffer.Bind(gl.ARRAY_BUFFER)
	l.MProgram.ProgramObject.GetAttribLocation("a_texCoord").AttribPointer(2, gl.FLOAT, false, 0, nil)
	l.MProgram.ProgramObject.GetAttribLocation("a_texCoord").EnableArray()
	CharLen := len([]rune(l.Text))

	gl.DrawArrays(gl.TRIANGLES, 0, CharLen*6)
	//gl.Disable(gl.ALPHA_TEST)
	gl.Disable(gl.BLEND)
	l.VBuffer.Unbind(gl.ARRAY_BUFFER)
	l.TexBuffer.Unbind(gl.ARRAY_BUFFER)
}
